const nodemailer = require('nodemailer');
const Core = require('@alicloud/pop-core');
const notificationConfig = require('../config/notification');
const sqlPool = require('../DB/sqlPool');
const sqlConfig = require('../DB/sqlConfig');

// 验证码有效期（分钟）
const EXPIRATION_TIME = 10;

/**
 * 生成随机验证码
 * @param {number} length 验证码长度
 * @returns {string} 验证码
 */
function generateCode(length = 6) {
    let code = '';
    for (let i = 0; i < length; i++) {
        code += Math.floor(Math.random() * 10);
    }
    return code;
}

/**
 * 保存验证码到数据库
 * @param {string} type 验证码类型 (email/phone)
 * @param {string} account 邮箱或手机号
 * @param {string} code 验证码
 * @param {string} purpose 用途 (register/login/reset)
 */
async function saveVerifyCode(type, account, code, purpose) {
    try {
        // 验证码表若不存在则创建
        await sqlPool.queryData(`
            CREATE TABLE IF NOT EXISTS verify_codes (
                id INT AUTO_INCREMENT PRIMARY KEY,
                type VARCHAR(10) NOT NULL COMMENT '验证码类型(email/phone)',
                account VARCHAR(100) NOT NULL COMMENT '邮箱或手机号',
                code VARCHAR(10) NOT NULL COMMENT '验证码',
                purpose VARCHAR(20) NOT NULL COMMENT '用途(register/login/reset)',
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                expires_at DATETIME NOT NULL,
                used TINYINT(1) DEFAULT 0 COMMENT '是否已使用'
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
        `);
        
        // 设置过期时间
        const expiresAt = new Date();
        expiresAt.setMinutes(expiresAt.getMinutes() + EXPIRATION_TIME);
        
        // 保存验证码
        await sqlPool.queryData(
            `INSERT INTO verify_codes (type, account, code, purpose, expires_at) 
             VALUES (?, ?, ?, ?, ?)`,
            [type, account, code, purpose, expiresAt]
        );
        
        return true;
    } catch (error) {
        console.error('保存验证码失败:', error);
        return false;
    }
}

/**
 * 验证验证码是否有效
 * @param {string} type 验证码类型 (email/phone)
 * @param {string} account 邮箱或手机号
 * @param {string} code 验证码
 * @param {string} purpose 用途 (register/login/reset)
 * @returns {Promise<boolean>} 验证结果
 */
async function verifyCode(type, account, code, purpose) {
    try {
        const { rows } = await sqlPool.queryData(
            `SELECT * FROM verify_codes 
             WHERE type = ? AND account = ? AND code = ? AND purpose = ? 
             AND used = 0 AND expires_at > NOW() 
             ORDER BY id DESC LIMIT 1`,
            [type, account, code, purpose]
        );
        
        if (rows && rows.length > 0) {
            // 标记验证码为已使用
            await sqlPool.queryData(
                `UPDATE verify_codes SET used = 1 WHERE id = ?`,
                [rows[0].id]
            );
            return true;
        }
        
        return false;
    } catch (error) {
        console.error('验证码验证失败:', error);
        return false;
    }
}

/**
 * 发送邮箱验证码
 * @param {string} email 邮箱地址
 * @param {string} purpose 用途 (register/login/reset)
 * @returns {Promise<{success: boolean, code?: string, message?: string}>}
 */
async function sendEmailCode(email, purpose) {
    try {
        const code = generateCode();
        const subject = {
            'register': '注册验证码',
            'login': '登录验证码',
            'reset': '重置密码验证码'
        }[purpose] || '验证码';
        
        // 创建邮件发送器
        const transporter = nodemailer.createTransport(notificationConfig.email);
        
        // 发送邮件
        await transporter.sendMail({
            from: notificationConfig.email.from,
            to: email,
            subject: `【IT猴社区】${subject}`,
            html: `
                <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #eee; border-radius: 5px;">
                    <h2 style="color: #333;">IT猴社区 - ${subject}</h2>
                    <p>您好，您的验证码是：</p>
                    <div style="background-color: #f5f5f5; padding: 10px; font-size: 24px; font-weight: bold; text-align: center; letter-spacing: 5px; margin: 20px 0;">
                        ${code}
                    </div>
                    <p>验证码有效期为 ${EXPIRATION_TIME} 分钟，请勿泄露给他人。</p>
                    <p>如非本人操作，请忽略此邮件。</p>
                    <div style="margin-top: 30px; padding-top: 10px; border-top: 1px solid #eee; color: #999; font-size: 12px;">
                        <p>此邮件由系统自动发送，请勿回复。</p>
                    </div>
                </div>
            `
        });
        
        // 保存验证码
        await saveVerifyCode('email', email, code, purpose);
        
        return {
            success: true,
            code
        };
    } catch (error) {
        console.error('发送邮箱验证码失败:', error);
        return {
            success: false,
            message: error.message
        };
    }
}

/**
 * 发送短信验证码
 * @param {string} phone 手机号
 * @param {string} purpose 用途 (register/login/reset)
 * @returns {Promise<{success: boolean, code?: string, message?: string}>}
 */
async function sendSMSCode(phone, purpose) {
    try {
        const code = generateCode();
        
        // 阿里云短信客户端
        const client = new Core({
            accessKeyId: notificationConfig.aliyunSMS.accessKeyId,
            accessKeySecret: notificationConfig.aliyunSMS.accessKeySecret,
            endpoint: 'https://dysmsapi.aliyuncs.com',
            apiVersion: '2017-05-25'
        });
        
        // 短信模板代码
        const templateCode = notificationConfig.aliyunSMS.templateCode[purpose];
        if (!templateCode) {
            throw new Error(`未找到短信模板: ${purpose}`);
        }
        
        // 发送短信
        const params = {
            RegionId: 'cn-hangzhou',
            PhoneNumbers: phone,
            SignName: notificationConfig.aliyunSMS.signName,
            TemplateCode: templateCode,
            TemplateParam: JSON.stringify({ code })
        };
        
        const requestOption = {
            method: 'POST'
        };
        
        await client.request('SendSms', params, requestOption);
        
        // 保存验证码
        await saveVerifyCode('phone', phone, code, purpose);
        
        return {
            success: true,
            code
        };
    } catch (error) {
        console.error('发送短信验证码失败:', error);
        return {
            success: false,
            message: error.message
        };
    }
}

module.exports = {
    generateCode,
    verifyCode,
    sendEmailCode,
    sendSMSCode
}; 